/*******************************************************************************
 * File name: 		main.c
 * Description: 	GPDMA controller usage
 * Project: 		GPDMA
 * Target: 			LPC2478
 * Compiler: 		arm-none-eabi-gcc
 * Date: 			2010-12-02
 * Author: 			Kuba
 * Based on: -
 *******************************************************************************/

/*==============================================================================
 Includes
==============================================================================*/
# include <stdbool.h>
# include "LPC24xx.h"
# include "typedef.h"
# include "init.h"
# include "irq.h"
# include "board.h"
# include "timer.h"
# include "uart.h"
# include "printf.h"
# include "gpdma.h"

/*==============================================================================
 Defines
==============================================================================*/
# define GPDMA_LLI            0
# define GPDMA_LLI_NUM        4
# define GPDMA_SRC            0x7FD00400
# define GPDMA_DST            0x7FD00C00
# define GPDMA_XFER_SIZE      32
# define GPDMA_PATTERN        0x44

/*==============================================================================
 Globals
==============================================================================*/
   /* GPDMA */
static struct gpdmaConf mygpdma;
static gpdmaChannel mychannel;
struct uart u0;
//static struct tmr t0;
# if GPDMA_LLI
static struct list gpdmaList[GPDMA_LLI_NUM]__attribute__ ((section(".gpdma_list")));
static uint32 srcAddr[] = {GPDMA_SRC, GPDMA_SRC + 0x40, GPDMA_SRC + 0x80, GPDMA_SRC + 0xC0};
static uint32 dstAddr[] = {GPDMA_DST, GPDMA_DST + 0x40, GPDMA_DST + 0x80, GPDMA_DST + 0xC0};
# endif

/*==============================================================================
 Static function prototypes
==============================================================================*/
static void jtagDelay 		(void);
static void swiLedOn 		(void);
static void swiLedOff 		(void);
# if GPDMA_LLI
static void fillLliBuff		(uint8 pattern);
static void testLli        (void);
# else
static void fillGpdmaTxBuff  (uint8 pattern);
static void fillGpdmaRxBuff  (uint8 pattern);
static void test			   (void);
# endif
//static void endTransfer    (void);
static void error          (void);
/*==============================================================================
 Main function
==============================================================================*/
int main(void)
{
	/* ARM initialization */
	jtagDelay();
	systemInit ();
	vicInit();								/* VIC initialization */
	irqEnableCpsr();                 /* enable IRQs */

	/* peripherals initialization */
	/* leds */
	ledInit();
   /* uart */
   u0.uartNo            = uart2;
   u0.baud              = baud9600;
   u0.wordLen           = word8BIT;
   u0.stopBit           = stop1BIT;
   u0.parity            = parityDISABLE;
   u0.paritySel         = parityODD;
   u0.breakCtrl         = breakCTRL_DISABLE;
   u0.fifo              = 0;
   u0.intrpt            = 0;
   u0.intrptTxTrig      = 0;
   u0.intrptRxTrig      = 0;
   u0.buffers.txBuff    = 0;
   u0.buffers.txBuffSize= 0;
   u0.buffers.rxBuff    = 0;
   u0.buffers.rxBuffSize= 0;
   uartInit (&u0);   /* messages via RS232 */
   uprintf ("%s\n", "*** Hey hey, GPDMA! ***");

   gpdmaInit(irqPRIORITY7);

# if GPDMA_LLI
	fillLliBuff(GPDMA_PATTERN);
# else
   fillGpdmaTxBuff(GPDMA_PATTERN);
   fillGpdmaRxBuff(0xaa);
# endif
   mygpdma.mode            = gpdmaM2M;
   mygpdma.srcWidth        = gpdmaS_WIDTH8;
   mygpdma.dstWidth        = gpdmaD_WIDTH8;
   mygpdma.sbSize          = gpdmaSB_SIZE4;
   mygpdma.dbSize          = gpdmaDB_SIZE4;
   mygpdma.srcPeriph       = 0;
   mygpdma.dstPeriph       = 0;
   mygpdma.flowCtrl        = gpdmaFLOW_CTRL_M2M_DMA;
   mygpdma.srcAddr         = GPDMA_SRC;
   mygpdma.dstAddr         = GPDMA_DST;
   mygpdma.transferEndService = test;
   mygpdma.errorService = error;
   mychannel = gpdmaChnl0Init(&mygpdma);
   gpdmaChnl0Enable(mychannel, GPDMA_XFER_SIZE);

	uint32 i;
	while (1)
	{
		swiLedOn();
		for (i = 0; i < 5000000; ++i);
		swiLedOff();
		for (i = 0; i < 5000000; ++i);

	}
	return 0;
}

/*==============================================================================
 Static function definitions
==============================================================================*/
/*------------------------------------------------------------------------------
 function name:	jtagDelay
 description:		function provides a delay required by jtag
 parameters:		none
 returned value:	none
------------------------------------------------------------------------------*/

static void jtagDelay (void)
{
	volatile unsigned int i;
	for (i = 0; i < 200000; ++i);
}

# if GPDMA_LLI
/*------------------------------------------------------------------------------
 function name:	fillLliBuff
 description:		fill LLI buffers for GPDMA transmission
 parameters:		pattern
 returned value: 	none
------------------------------------------------------------------------------*/
static void fillLliBuff	(uint8 pattern)
{
	uint8 i;
	uint8 *p;

	p= (uint8 *)GPDMA_SRC;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      *(p + i) = pattern;
   }
   *(p + 2) = 0x11;
   *(p + 10) = 0x22;

   p= (uint8 *)GPDMA_SRC + 0x40;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      *(p + i) = pattern;
   }
   *(p + 2) = 0x33;
   *(p + 10) = 0x44;

   p= (uint8 *)GPDMA_SRC + 0x80;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      *(p + i) = pattern;
   }
   *(p + 2) = 0x55;
   *(p + 10) = 0x66;

   p= (uint8 *)GPDMA_SRC + 0xC0;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      *(p + i) = pattern;
   }
   *(p + 2) = 0x77;
   *(p + 10) = 0x88;
}

/*------------------------------------------------------------------------------
 function name:   testLli
 description:     test LLI buffers
 parameters:      none
 returned value:  none
------------------------------------------------------------------------------*/
static void testLli (void)
{
   uint8 i;
   uint8 *p;

   p = (uint8 *)GPDMA_DST;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      if (i == 2 || i == 10)
      {
         uprintf ("i: %d, content:%x\n", i, *(p + i));
         continue;
      }
      if (*(p + i) != GPDMA_PATTERN)
      {
         uprintf ("ERROR, i: %d, content:%x\n", i, *(p + i));
         while (1);
      }
   }
   uprintf ("%s\n", "first LLI ok");

   p = (uint8 *)GPDMA_DST + 0x40;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      if (i == 2 || i == 10)
      {
         uprintf ("i: %d, content:%x\n", i, *(p + i));
         continue;
      }
      if (*(p + i) != GPDMA_PATTERN)
      {
         uprintf ("ERROR, i: %d, content:%x\n", i, *(p + i));
         while (1);
      }
   }
   uprintf ("%s\n", "second LLI ok");

   p = (uint8 *)GPDMA_DST + 0x80;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      if (i == 2 || i == 10)
      {
         uprintf ("i: %d, content:%x\n", i, *(p + i));
         continue;
      }
      if (*(p + i) != GPDMA_PATTERN)
      {
         uprintf ("ERROR, i: %d, content:%x\n", i, *(p + i));
         while (1);
      }
   }
   uprintf ("%s\n", "third LLI ok");

   p = (uint8 *)GPDMA_DST + 0xC0;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      if (i == 2 || i == 10)
      {
         uprintf ("i: %d, content:%x\n", i, *(p + i));
         continue;
      }
      if (*(p + i) != GPDMA_PATTERN)
      {
         uprintf ("ERROR, i: %d, content:%x\n", i, *(p + i));
         while (1);
      }
   }
   uprintf ("%s\n", "fourth LLI ok");

}
# else
/*------------------------------------------------------------------------------
 function name:   fillGpdmaTxBuff
 description:     fill GPDMA TX buffer
 parameters:      pattern
 returned value:  none
------------------------------------------------------------------------------*/
static void fillGpdmaTxBuff  (uint8 pattern)
{
   uint8 i;
   uint8 *p;

   p= (uint8 *)GPDMA_SRC;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      *(p + i) = pattern;
   }
   *(p + 2) = 0x44;
   *(p + 10) = 0x66;
}

/*------------------------------------------------------------------------------
 function name:   fillGpdmaRxBuff
 description:     fill GPDMA TX buffer
 parameters:      pattern
 returned value:  none
------------------------------------------------------------------------------*/
static void fillGpdmaRxBuff  (uint8 pattern)
{
   uint8 i;
   uint8 *p;

   p= (uint8 *)GPDMA_DST;
   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      *(p + i) = pattern;
   }
}

/*------------------------------------------------------------------------------
 function name:   test
 description:     test if GPDMA transffered data correctly
 parameters:      none
 returned value:  none
------------------------------------------------------------------------------*/
static void test (void)
{
   uint8 i;
   uint8 *p = (uint8 *)GPDMA_DST;

   for (i = 0; i < GPDMA_XFER_SIZE; ++i)
   {
      if (i == 2 || i == 10)
      {
         uprintf ("i: %d, content:%x\n", i, *(p + i));
         continue;
      }
      if (*(p + i) != GPDMA_PATTERN)
      {
         uprintf ("ERROR, i: %d, content:%x\n", i, *(p + i));
         while (1);
      }
   }
   uprintf ("%s\n", "GPDMA test ok");
}
# endif
/*------------------------------------------------------------------------------
 function name:	swiLedOn
 description:		led effect by SWI interrupt
 parameters:		none
 returned value: 	none
------------------------------------------------------------------------------*/
static void swiLedOn ()
{
	asm volatile ("swi #1\n\t");
}

/*------------------------------------------------------------------------------
 function name:	swiLedOff
 description:		led effect by SWI interrupt
 parameters:		none
 returned value: 	none
------------------------------------------------------------------------------*/
static void swiLedOff ()
{
	asm volatile ("swi #2\n\t");
}

/*------------------------------------------------------------------------------
 function name:   endTransfer
 description:     service
 parameters:      none
 returned value:  none
------------------------------------------------------------------------------*/

static void error  (void)
{
   return;
}

/******************************************************************************
* END OF FILE
******************************************************************************/
